home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / units / graphics.pas < prev    next >
Pascal/Delphi Source File  |  1994-04-04  |  30KB  |  1,092 lines

  1. UNIT Graphics; { Intended at 16 color graphics unit }
  2.  
  3. INTERFACE
  4.  
  5. {╔═════════════════════════════════════════════════════════════════════════╗
  6.  ║ Useful constants for modes & colors                                     ║
  7.  ╚═════════════════════════════════════════════════════════════════════════╝}
  8.  
  9. CONST     { HI nibble is mode number, LO is data }
  10.           Vga640x480x016=$02; { 2 = 4 bit graphics mode }
  11.           Ega640x200x016=$12;
  12.           Ega640x350x016=$22;
  13.           Txt080x025x016=$00; { 0 = textmode }
  14.           Txt080x050x016=$10;
  15.           Txt080xOwnFont=$20;
  16.           UnknownGfxMode=$FF;
  17.  
  18.           ON           =TRUE; OFF         =FALSE;
  19.  
  20.           Black         =  0; Blue          =  1;
  21.           Green         =  2; Cyan          =  3;
  22.           Red           =  4; Magenta       =  5;
  23.           Brown         =  6; LightGray     =  7;
  24.           DarkGray      =  8; LightBlue     =  9;
  25.           LightGreen    = 10; LightCyan     = 11;
  26.           LightRed      = 12; LightMagenta  = 13;
  27.           Yellow        = 14; White         = 15;
  28.  
  29.           None          =  0; Left          =  1;
  30.           Right         =  2; Both          =  3;
  31.  
  32.           FourBitDac    : ARRAY[0..15] OF BYTE=
  33.                           (0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63);
  34.  
  35. {╔═════════════════════════════════════════════════════════════════════════╗
  36.  ║ Objects for easier handling of larger graphical structures              ║
  37.  ╚═════════════════════════════════════════════════════════════════════════╝}
  38.  
  39. TYPE      Bob=OBJECT
  40.             fore,back:ARRAY[0..23,0..23] OF BYTE;
  41.             px,py,ignore:BYTE;
  42.             PROCEDURE Clear;
  43.             PROCEDURE SetFore(x,y:WORD);
  44.             PROCEDURE GetFore(xa,ya,xb,yb:WORD; ig:BYTE);
  45.             PROCEDURE SetBack(x,y:WORD);
  46.             PROCEDURE GetBack(x,y:WORD);
  47.             PROCEDURE Save(name:STRING);
  48.             PROCEDURE Load(name:STRING);
  49.           END;
  50.  
  51.           Button=OBJECT
  52.             xa,ya,xb,yb:WORD; fg,bg,hl,sd:BYTE;
  53.             title,oldtt:STRING; press:BOOLEAN;
  54.             PROCEDURE Draw;
  55.             PROCEDURE Remove;
  56.             PROCEDURE Init(ax,ay,bx,by:WORD; f,b,h,s:BYTE; t:STRING);
  57.             FUNCTION  Quick(ms:WORD):BOOLEAN;
  58.             FUNCTION  Pressed:BOOLEAN;
  59.             FUNCTION  Switched:BOOLEAN;
  60.           END;
  61.  
  62.           TextFrame=OBJECT
  63.             xp,yp:WORD; tc,bh,bs,bk,sz:BYTE; data,what:STRING;
  64.             PROCEDURE Draw;
  65.             PROCEDURE Init(x,y:WORD; a,b,c,d,l:BYTE; s,t:STRING);
  66.             FUNCTION  Inside:BOOLEAN;
  67.             PROCEDURE Remove(color:BYTE);
  68.           END;
  69.  
  70. {╔═════════════════════════════════════════════════════════════════════════╗
  71.  ║ Important variables and settings                                        ║
  72.  ╚═════════════════════════════════════════════════════════════════════════╝}
  73.  
  74. TYPE      DACBUFFER=ARRAY[0..255,0..2] OF BYTE;
  75.  
  76. VAR       WhatGfxMode   ,
  77.           FontHeight    ,
  78.           MouseButtons  :BYTE;
  79.           VideoSegment  ,
  80.           xMax          ,
  81.           yMax          ,
  82.           FontSegment   ,
  83.           FontOffset    ,
  84.           MouseXpos     ,
  85.           MouseYpos     :WORD;
  86.           MouseBob      :BOB;
  87.           MouseHardWare ,
  88.           MouseState    :BOOLEAN;
  89.           MouseHardBob  :ARRAY[0..33] OF WORD;
  90.  
  91. {╔═════════════════════════════════════════════════════════════════════════╗
  92.  ║ General procedures, vital graphic procedures                            ║
  93.  ╚═════════════════════════════════════════════════════════════════════════╝}
  94.  
  95. FUNCTION  GraphicsMode(mode:BYTE):BOOLEAN;
  96. PROCEDURE SetPix(x,y:WORD; color:BYTE);
  97. FUNCTION  GetPix(x,y:WORD):BYTE;
  98. PROCEDURE Hline(xa,xb,y:WORD; color:BYTE);
  99. PROCEDURE Vline(x,ya,yb:WORD; color:BYTE);
  100. PROCEDURE Box(xa,ya,xb,yb:WORD; color:BYTE);
  101. PROCEDURE Fbox(xa,ya,xb,yb:WORD; color:BYTE);
  102. PROCEDURE Clear(color:BYTE);
  103. PROCEDURE Line(xa,ya,xb,yb:INTEGER; color:BYTE);
  104. PROCEDURE PutMap(x,y:WORD; VAR map:POINTER; ignore:BYTE);
  105. PROCEDURE GetMap(x,y:WORD; VAR map:POINTER);
  106.  
  107. {╔═════════════════════════════════════════════════════════════════════════╗
  108.  ║ Procedures for handling fonts, mostly based on pointers                 ║
  109.  ╚═════════════════════════════════════════════════════════════════════════╝}
  110.  
  111. FUNCTION  MainFont(font:POINTER):POINTER; { leaves pointer to OLD mainfont }
  112. FUNCTION  WhatFont:POINTER;               { leaves pointer to THE mainfont }
  113. PROCEDURE PlotChar(x,y:WORD; ch,color,bg:BYTE);
  114. PROCEDURE DrawChar(x,y:WORD; ch,color:BYTE);
  115. PROCEDURE WriteLine(x,y:WORD; s:STRING; color,bg:BYTE);
  116.  
  117. {╔═════════════════════════════════════════════════════════════════════════╗
  118.  ║ DAC color controller procedures                                         ║
  119.  ╚═════════════════════════════════════════════════════════════════════════╝}
  120.  
  121. PROCEDURE DacSetSingle(nr,red,green,blue:BYTE);
  122. PROCEDURE DacGetSingle(nr:BYTE; VAR red,green,blue:BYTE);
  123. PROCEDURE DacSetPalette(dac:DACBUFFER);
  124. PROCEDURE DacGetPalette(VAR dac:DACBUFFER);
  125. PROCEDURE DacSavePalette(name:STRING; dac:DACBUFFER);
  126. PROCEDURE DacLoadPalette(name:STRING; VAR dac:DACBUFFER);
  127.  
  128. {╔═════════════════════════════════════════════════════════════════════════╗
  129.  ║ Mouse routines with interrupt handling on $1C                           ║
  130.  ╚═════════════════════════════════════════════════════════════════════════╝}
  131.  
  132. PROCEDURE MouseSetArrowBob;
  133. PROCEDURE MouseSetClockBob;
  134. PROCEDURE MouseUseHardware;
  135. PROCEDURE MouseUseSoftware;
  136. FUNCTION  MouseReset:BOOLEAN;
  137. PROCEDURE Mouse(mode:BOOLEAN);
  138. PROCEDURE MouseSetPosition(x,y:WORD);
  139. PROCEDURE MouseSetRange(xa,ya,xb,yb:WORD);
  140. FUNCTION  MouseInitiateInterrupt:BOOLEAN;
  141. PROCEDURE MouseEndInterrupt;
  142.  
  143. IMPLEMENTATION
  144.  
  145. {╔═════════════════════════════════════════════════════════════════════════╗
  146.  ║ Procedures only visible within this unit                                ║
  147.  ╚═════════════════════════════════════════════════════════════════════════╝}
  148.  
  149. VAR       ScanCode:BYTE;
  150.  
  151. FUNCTION  InterruptVector(pntr:POINTER; itr:BYTE):POINTER;
  152.  BEGIN
  153.    ASM CLI END;
  154.    InterruptVector:=Ptr(MemW[0:itr*4+2],MemW[0:itr*4]);
  155.    MemW[0:itr*4]:=Ofs(pntr^); MemW[0:itr*4+2]:=Seg(pntr^);
  156.    ASM STI END;
  157.  END;
  158.  
  159. FUNCTION  KeyWaiting:BOOLEAN; ASSEMBLER;
  160.  ASM
  161.      MOV  ax,$0040
  162.      MOV  es,ax
  163.      MOV  al,FALSE
  164.      MOV  bx,es:[$001A]
  165.      CMP  bx,es:[$001C]
  166.      JE   @qt
  167.      MOV  al,TRUE
  168. @qt:
  169.  END;
  170.  
  171. FUNCTION  Len(stg:STRING):BYTE; ASSEMBLER;
  172.  ASM
  173.      LES  di,stg
  174.      MOV  al,es:[di]
  175.  END;
  176.  
  177. FUNCTION  GetKey:CHAR; ASSEMBLER; { with wait if no key }
  178.  ASM
  179.      MOV  ax,$0040
  180.      MOV  es,ax
  181. @wt: MOV  bx,es:[$001A]
  182.      CMP  bx,es:[$001C]
  183.      JZ   @wt
  184.      MOV  ax,es:[bx]
  185.      MOV  ScanCode,AH
  186.      ADD  bx,2
  187.      CMP  bx,es:[$0082]
  188.      JB   @nx           { buffer not at end }
  189.      MOV  bx,es:[$0080]
  190. @nx: MOV  es:[$001A],bx
  191.  END;
  192.  
  193. {╔═════════════════════════════════════════════════════════════════════════╗
  194.  ║ Objects for easier handling of larger graphical structures              ║
  195.  ╚═════════════════════════════════════════════════════════════════════════╝}
  196.  
  197. PROCEDURE Bob.Clear;
  198.  BEGIN
  199.    px:=0; py:=0; ignore:=0; fore[0,0]:=0; back[0,0]:=0;
  200.  END;
  201.  
  202. PROCEDURE Bob.SetFore(x,y:WORD);
  203.  VAR a,b:BYTE;
  204.  BEGIN
  205.    FOR a:=0 TO px DO FOR b:=0 TO py DO
  206.     IF fore[a,b]<>ignore THEN SetPix(x+a,y+b,fore[a,b]);
  207.  END;
  208.  
  209. PROCEDURE Bob.GetFore(xa,ya,xb,yb:WORD; ig:BYTE);
  210.  VAR a,b:BYTE;
  211.  BEGIN
  212.    px:=xb-xa; py:=yb-ya; ignore:=ig;
  213.    FOR a:=0 TO px DO FOR b:=0 TO py DO fore[a,b]:=GetPix(xa+a,ya+b);
  214.  END;
  215.  
  216. PROCEDURE Bob.SetBack(x,y:WORD);
  217.  VAR a,b:BYTE;
  218.  BEGIN
  219.    FOR a:=0 TO px DO FOR b:=0 TO py DO SetPix(x+a,y+b,back[a,b]);
  220.  END;
  221.  
  222. PROCEDURE Bob.GetBack(x,y:WORD);
  223.  VAR a,b:BYTE;
  224.  BEGIN
  225.    FOR a:=0 TO px DO FOR b:=0 TO py DO back[a,b]:=GetPix(x+a,y+b);
  226.  END;
  227.  
  228. PROCEDURE Bob.Save(name:STRING);
  229.  VAR fil:FILE OF BYTE; a,b:BYTE;
  230.  BEGIN
  231.    Assign(fil,name);
  232.    ReWrite(fil);
  233.    Write(fil,px);
  234.    Write(fil,py);
  235.    Write(fil,ignore);
  236.    FOR b:=0 TO py DO FOR a:=0 TO px DO Write(fil,fore[a,b]);
  237.    Close(fil);
  238.  END;
  239.  
  240. PROCEDURE Bob.Load(name:STRING);
  241.  VAR fil:FILE OF BYTE; a,b:BYTE;
  242.  BEGIN
  243.    Assign(fil,name);
  244.    Reset(fil);
  245.    Read(fil,px);
  246.    Read(fil,py);
  247.    Read(fil,ignore);
  248.    FOR b:=0 TO py DO FOR a:=0 TO px DO Read(fil,fore[a,b]);
  249.    Close(fil);
  250.  END;
  251.  
  252. {───────────────────────────────────────────────────────────────────────────}
  253.  
  254. PROCEDURE Button.Draw;
  255.  VAR a,b:BYTE; ms:BOOLEAN;
  256.  BEGIN
  257.    ms:=MouseState; Mouse(OFF);
  258.    IF press THEN BEGIN a:=fg; fg:=sd; b:=hl; hl:=sd; sd:=b; END;
  259.    Box(xa,ya,xb,yb,0);
  260.    HLine(Xa+1,Xb-2,Ya+1,Hl); VLine(Xa+1,Ya+1,Yb-1,Hl);
  261.    HLine(Xa+2,Xb-1,Yb-1,Sd); VLine(Xb-1,Ya+1,Yb-1,Sd);
  262.    HLine(Xa+2,Xb-3,Ya+2,Hl); VLine(Xa+2,Ya+2,Yb-2,Hl);
  263.    HLine(Xa+3,Xb-2,Yb-2,Sd); VLine(Xb-2,Ya+2,Yb-2,Sd);
  264.    IF oldtt<>title THEN
  265.     BEGIN
  266.       Fbox(xa+3,ya+3,xb-3,yb-3,bg); oldtt:=title;
  267.     END;
  268.    WriteLine(xa+1+(xb-xa-Len(title)*8) DIV 2,
  269.             ya+1+((yb-ya) DIV 2)-FontHeight DIV 2,title,fg,bg);
  270.    IF press THEN BEGIN fg:=a; sd:=hl; hl:=b; END;
  271.    Mouse(ms);
  272.  END;
  273.  
  274. PROCEDURE Button.Remove;
  275.  VAR ms:BOOLEAN;
  276.  BEGIN
  277.    ms:=MouseState; Mouse(OFF);
  278.    Fbox(xa,ya,xb,yb,bg);
  279.    Mouse(ms);
  280.  END;
  281.  
  282. PROCEDURE Button.Init(ax,ay,bx,by:WORD; f,b,h,s:BYTE; t:STRING);
  283.  BEGIN
  284.    xa:=ax; ya:=ay; xb:=bx; yb:=by; press:=OFF; oldtt:='';
  285.    fg:=f;  bg:=b;  hl:=h;  sd:=s;  title:=t;
  286.  END;
  287.  
  288. FUNCTION  Button.Quick(ms:WORD):BOOLEAN;
  289.  BEGIN
  290.    Quick:=FALSE; IF MouseButtons=None THEN Exit;
  291.    IF (MouseXpos>=xa) AND (MouseYpos>=ya) AND
  292.       (MouseXpos<=xb) AND (MouseYpos<=yb) THEN
  293.     BEGIN
  294.       Quick:=TRUE;
  295.        ASM
  296.          MOV ax,1000
  297.          MUL ms
  298.          MOV cx,dx
  299.          MOV dx,ax
  300.          MOV ah,$86
  301.          INT $15
  302.        END;
  303.     END;
  304.  END;
  305.  
  306. FUNCTION  Button.Pressed:BOOLEAN;
  307.  BEGIN
  308.    Pressed:=FALSE; IF MouseButtons=None THEN Exit;
  309.    IF (MouseXpos>=xa) AND (MouseYpos>=ya) AND
  310.       (MouseXpos<=xb) AND (MouseYpos<=yb) THEN
  311.     BEGIN
  312.       press:=NOT press; Draw;
  313.       REPEAT UNTIL MouseButtons=None;
  314.       IF (MouseXpos>=xa) AND (MouseYpos>=ya) AND
  315.          (MouseXpos<=xb) AND (MouseYpos<=yb) THEN Pressed:=TRUE;
  316.       press:=NOT press; Draw;
  317.     END;
  318.  END;
  319.  
  320. FUNCTION  Button.Switched:BOOLEAN;
  321.  BEGIN
  322.    Switched:=FALSE; IF MouseButtons=None THEN Exit;
  323.    IF (MouseXpos>=xa) AND (MouseYpos>=ya) AND
  324.       (MouseXpos<=xb) AND (MouseYpos<=yb) THEN
  325.     BEGIN
  326.       press:=NOT press; Draw;
  327.       REPEAT UNTIL MouseButtons=None;
  328.       Switched:=TRUE;
  329.     END;
  330.  END;
  331.  
  332. {───────────────────────────────────────────────────────────────────────────}
  333.  
  334. PROCEDURE TextFrame.Draw;
  335.  VAR ms:BOOLEAN;
  336.  BEGIN
  337.    ms:=MouseState; Mouse(OFF);
  338.    Fbox(xp,yp,xp+6+8*sz+8*Len(what),yp+6+FontHeight,bk);
  339.    Box (xp,yp,xp+6+8*sz+8*Len(what),yp+6+FontHeight,bs);
  340.    WriteLine(xp+3,yp+3,what+data,tc,bk);
  341.    Mouse(ms);
  342.  END;
  343.  
  344. PROCEDURE TextFrame.Init(x,y:WORD; a,b,c,d,l:BYTE; s,t:STRING);
  345.  BEGIN
  346.    xp:=x; yp:=y; tc:=a; bk:=b; bh:=c; bs:=d;
  347.    sz:=l+1; what:=s; data:=t;
  348.  END;
  349.  
  350. FUNCTION  TextFrame.Inside:BOOLEAN;
  351.  VAR a,b:WORD; ms:BOOLEAN; c:CHAR;
  352.  BEGIN
  353.    a:=xp+6+8*(Len(what)+sz);
  354.    b:=yp+6+FontHeight;
  355.    IF (MouseXpos<xp) OR (MouseYpos<yp) OR
  356.       (MouseXpos> a) OR (MouseYpos> b) THEN Exit;
  357.    ms:=MouseState; Mouse(OFF);
  358.    Box(xp,yp,xp+6+8*sz+8*Len(what),yp+6+FontHeight,bh);
  359.    Hline(xp+3+8*(Len(what)+Len(data)),
  360.          xp+3+8*(Len(what)+Len(data))+8,yp+FontHeight+3,tc);
  361.    Mouse(ms);
  362.    WHILE (MouseXpos>=xp) AND (MouseYpos>=yp) AND
  363.          (MouseXpos<= a) AND (MouseYpos<= b) DO
  364.     BEGIN
  365.       IF KeyWaiting THEN
  366.        BEGIN
  367.          Mouse(OFF);
  368.          Hline(xp+3+8*(Len(what)+Len(data)),
  369.                xp+3+8*(Len(what)+Len(data))+8,yp+FontHeight+3,bk);
  370.          c:=GetKey;
  371.          CASE c OF
  372.           #13: ;
  373.           #9:  ;
  374.           #8: IF (Len(data)>0) THEN
  375.                BEGIN
  376.                  data[Len(data)]:=' ';
  377.                  WriteLine(xp+3,yp+3,what+data,tc,bk);
  378.                  data:=Copy(data,1,Len(data)-1);
  379.                END;
  380.           ELSE IF (Len(data)<sz-1) THEN
  381.            BEGIN
  382.              data:=data+c;
  383.              WriteLine(xp+3,yp+3,what+data,tc,bk);
  384.            END;
  385.          END;
  386.          Hline(xp+3+8*(Len(what)+Len(data)),
  387.                xp+3+8*(Len(what)+Len(data))+8,yp+FontHeight+3,tc);
  388.          Mouse(ms);
  389.        END;
  390.     END;
  391.    Mouse(OFF);
  392.    Box(xp,yp,xp+6+8*sz+8*Len(what),yp+6+FontHeight,bs);
  393.    Hline(xp+3+8*(Len(what)+Len(data)),
  394.          xp+3+8*(Len(what)+Len(data))+8,yp+FontHeight+3,bk);
  395.    Mouse(ms);
  396.  END;
  397.  
  398. PROCEDURE TextFrame.Remove(color:BYTE);
  399.  VAR ms:BOOLEAN;
  400.  BEGIN
  401.    ms:=MouseState; Mouse(OFF);
  402.    Box(xp,yp,xp+6+8*sz+8*Len(what),yp+6+FontHeight,color);
  403.    Mouse(ms);
  404.  END;
  405.  
  406. {╔═════════════════════════════════════════════════════════════════════════╗
  407.  ║ General procedures, vital graphic procedures                            ║
  408.  ╚═════════════════════════════════════════════════════════════════════════╝}
  409.  
  410. FUNCTION  GraphicsMode(mode:BYTE):BOOLEAN; ASSEMBLER;
  411.  ASM
  412.      MOV  al,mode
  413.      CMP  al,Vga640x480x016
  414.      JE   @ma
  415.      CMP  al,Ega640x200x016
  416.      JE   @mb
  417.      CMP  al,Ega640x350x016
  418.      JE   @mc
  419.      CMP  al,Txt080x025x016
  420.      JE   @md
  421.      CMP  al,Txt080xOwnFont
  422.      JE   @me
  423.      MOV  al,FALSE
  424.      JMP  @qt
  425. @ma: MOV  WhatGfxMode,al
  426.      MOV  VideoSegment,$A000
  427.      MOV  xMax,639
  428.      MOV  yMax,479
  429.      MOV  ax,$0012
  430.      INT  $10
  431.      MOV  al,TRUE
  432.      JMP  @qt
  433. @mb: MOV  WhatGfxMode,al
  434.      MOV  VideoSegment,$A000
  435.      MOV  xMax,639
  436.      MOV  yMax,199
  437.      MOV  ax,$000E
  438.      INT  $10
  439.      MOV  al,TRUE
  440.      JMP  @qt
  441. @mc: MOV  WhatGfxMode,al
  442.      MOV  VideoSegment,$A000
  443.      MOV  xMax,639
  444.      MOV  yMax,349
  445.      MOV  ax,$0010
  446.      INT  $10
  447.      MOV  al,TRUE
  448.      JMP  @qt
  449. @md: MOV  WhatGfxMode,al
  450.      MOV  VideoSegment,$B800
  451.      MOV  xMax,79
  452.      MOV  yMax,24
  453.      MOV  ax,$0003
  454.      INT  $10
  455.      MOV  al,TRUE
  456.      JMP  @qt
  457. @me: MOV  WhatGfxMode,al
  458.      MOV  VideoSegment,$B800
  459.      MOV  xMax,79
  460.      MOV  ax,400
  461.      DIV  FontHeight
  462.      MOV  yMax,ax
  463.      MOV  ax,$0003
  464.      INT  $10
  465.      PUSH bp
  466.      MOV  ax,$1110
  467.      MOV  es,FontSegment
  468.      MOV  bp,FontOffset
  469.      MOV  cx,$0100
  470.      MOV  dx,$0000
  471.      MOV  bh,es:[bp-1]
  472.      MOV  bl,$00
  473.      INT  $10
  474.      POP  BP
  475.      MOV  al,TRUE
  476.      JMP  @qt
  477. @qt:
  478.  END;
  479.  
  480. PROCEDURE SetPix(x,y:WORD; color:BYTE); ASSEMBLER;
  481.  ASM
  482.      MOV  ax,x
  483.      CMP  ax,xMax
  484.      JA   @qt
  485.      MOV  ax,y
  486.      CMP  ax,yMax
  487.      JA   @qt
  488.      MOV  es,VideoSegment
  489.      MOV  ch,color
  490.      MOV  ax,80
  491.      MUL  y
  492.      MOV  bx,x
  493.      MOV  cl,bl
  494.      SHR  bx,3
  495.      ADD  bx,ax
  496.      AND  cl,7
  497.      MOV  ax,$8008
  498.      SHR  ah,cl
  499.      MOV  dx,$3CE
  500.      OUT  dx,ax
  501.      MOV  ax,$0205
  502.      OUT  dx,ax
  503.      MOV  al,es:[bx]
  504.      MOV  es:[bx],ch
  505. {    MOV  ax,$FF08
  506.      OUT  dx,ax
  507.      MOV  ax,$0005
  508.      OUT  dx,ax      }
  509. @qt:
  510.  END;
  511.  
  512. FUNCTION  GetPix(x,y:WORD):BYTE; ASSEMBLER;
  513.  ASM
  514.      MOV  ax,80
  515.      MUL  y
  516.      MOV  si,x
  517.      MOV  cx,si
  518.      SHR  si,3
  519.      ADD  si,ax
  520.      AND  cl,7
  521.      XOR  cl,7
  522.      MOV  ch,1
  523.      SHL  ch,cl
  524.      MOV  ax,VideoSegment
  525.      MOV  es,ax
  526.      MOV  dx,$3CE
  527.      MOV  ax,(3 SHL 8)+4
  528.      XOR  bl,bl
  529. @la: OUT  dx,ax
  530.      MOV  bh,es:[si]
  531.      AND  bh,ch
  532.      NEG  bh
  533.      ROL  bx,1
  534.      DEC  ah
  535.      JGE  @la
  536.      MOV  al,bl
  537.  END;
  538.  
  539. PROCEDURE Hline(xa,xb,y:WORD; color:BYTE); ASSEMBLER;
  540.  ASM
  541.      MOV  es,VideoSegment
  542.      MOV  si,xa
  543.      MOV  di,y
  544.      MOV  ch,color
  545. @lp: MOV  ax,80
  546.      MUL  di
  547.      MOV  bx,si
  548.      MOV  cl,bl
  549.      SHR  bx,3
  550.      ADD  bx,ax
  551.      AND  cl,7
  552.      MOV  ah,128
  553.      SHR  ah,cl
  554.      MOV  dx,$3CE
  555.      MOV  al,8
  556.      OUT  dx,ax
  557.      MOV  ax,$0205
  558.      OUT  dx,ax
  559.      MOV  al,es:[bx]
  560.      MOV  es:[bx],ch
  561.      INC  si
  562.      CMP  si,xb
  563.      JBE  @lp
  564.  END;
  565.  
  566. PROCEDURE Vline(x,ya,yb:WORD; color:BYTE); ASSEMBLER;
  567.  ASM
  568.      MOV  es,VideoSegment
  569.      MOV  si,x
  570.      MOV  di,ya
  571.      MOV  ch,color
  572. @lp: MOV  ax,80
  573.      MUL  di
  574.      MOV  bx,si
  575.      MOV  cl,bl
  576.      SHR  bx,3
  577.      ADD  bx,ax
  578.      AND  cl,7
  579.      MOV  ah,128
  580.      SHR  ah,cl
  581.      MOV  dx,$3CE
  582.      MOV  al,8
  583.      OUT  dx,ax
  584.      MOV  ax,$0205
  585.      OUT  dx,ax
  586.      MOV  al,es:[bx]
  587.      MOV  es:[bx],ch
  588.      INC  di
  589.      CMP  di,yb
  590.      JBE  @lp
  591.  END;
  592.  
  593. PROCEDURE Box(xa,ya,xb,yb:WORD; color:BYTE);
  594.  BEGIN
  595.    Hline(xa,xb,ya,color); Hline(xa,xb,yb,color);
  596.    Vline(xa,ya,yb,color); Vline(xb,ya,yb,color);
  597.  END;
  598.  
  599. PROCEDURE Fbox(xa,ya,xb,yb:WORD; color:BYTE); ASSEMBLER;
  600.  ASM
  601.      MOV  es,VideoSegment
  602.      MOV  si,xa
  603.      MOV  di,ya
  604.      MOV  ch,color
  605. @lp: MOV  ax,80
  606.      MUL  di
  607.      MOV  bx,si
  608.      MOV  cl,bl
  609.      SHR  bx,3
  610.      ADD  bx,ax
  611.      AND  cl,7
  612.      MOV  ah,128
  613.      SHR  ah,cl
  614.      MOV  dx,$3CE
  615.      MOV  al,8
  616.      OUT  dx,ax
  617.      MOV  ax,$0205
  618.      OUT  dx,ax
  619.      MOV  al,es:[bx]
  620.      MOV  es:[bx],ch
  621.      INC  si
  622.      CMP  si,xb
  623.      JBE  @lp
  624.      MOV  si,xa
  625.      INC  di
  626.      CMP  di,yb
  627.      JBE  @lp
  628.  END;
  629.  
  630. PROCEDURE Clear(color:BYTE); ASSEMBLER;
  631.  ASM
  632.      MOV  es,VideoSegment
  633.      MOV  si,0
  634.      MOV  di,0
  635.      MOV  ch,color
  636. @lp: MOV  ax,80
  637.      MUL  di
  638.      MOV  bx,si
  639.      MOV  cl,bl
  640.      SHR  bx,3
  641.      ADD  bx,ax
  642.      AND  cl,7
  643.      MOV  ah,128
  644.      SHR  ah,cl
  645.      MOV  dx,$3CE
  646.      MOV  al,8
  647.      OUT  dx,ax
  648.      MOV  ax,$0205
  649.      OUT  dx,ax
  650.      MOV  al,es:[bx]
  651.      MOV  es:[bx],ch
  652.      INC  si
  653.      CMP  si,xMax
  654.      JBE  @lp
  655.      MOV  si,0
  656.      INC  di
  657.      CMP  di,yMax
  658.      JBE  @lp
  659.  END;
  660.  
  661. PROCEDURE Line(xa,ya,xb,yb:INTEGER; color:BYTE);
  662.  VAR d,dx,dy,ai,bi,xi,yi,x,y:INTEGER;
  663.  BEGIN
  664.    IF (Abs(xb-xa)<Abs(yb-ya)) THEN
  665.     BEGIN
  666.      IF ya>yb THEN
  667.       ASM
  668.         MOV AX,ya
  669.         MOV BX,yb
  670.         MOV ya,BX
  671.         MOV yb,AX
  672.         MOV AX,xa
  673.         MOV BX,xb
  674.         MOV xa,BX
  675.         MOV xb,AX
  676.       END;
  677.       IF (xb>xa) THEN Xi:=1 ELSE Xi:=-1;
  678.       Dy:=yb-ya; Dx:=Abs(xb-xa); D:=Dx*2-Dy; Ai:=2*(Dx-Dy);
  679.       Bi:=Dx*2; X:=xa; Y:=ya;
  680.       IF (X>=0) AND (Y>=0) AND (X<=Xmax) AND (Y<=Ymax) THEN SetPix(X,Y,color);
  681.       FOR Y:=ya+1 TO yb DO
  682.        BEGIN
  683.          IF (D>=0) THEN
  684.           ASM
  685.             MOV AX,X
  686.             ADD AX,Xi
  687.             MOV X,AX
  688.             MOV AX,D
  689.             ADD AX,Ai
  690.             MOV D,AX
  691.           END ELSE ASM
  692.             MOV AX,D
  693.             ADD AX,Bi
  694.             MOV D,AX
  695.           END;
  696.          IF (X>=0) AND (Y>=0) AND (X<=Xmax) AND (Y<=Ymax) THEN SetPix(X,Y,color);
  697.        END;
  698.     END ELSE BEGIN
  699.       IF (xa>xb) THEN
  700.        ASM
  701.          MOV AX,xa
  702.          MOV BX,xb
  703.          MOV xa,BX
  704.          MOV xb,AX
  705.          MOV AX,ya
  706.          MOV BX,yb
  707.          MOV ya,BX
  708.          MOV yb,AX
  709.        END;
  710.       IF (yb>ya) THEN Yi:=1 ELSE Yi:=-1;
  711.       Dx:=xb-xa; Dy:=Abs(yb-ya); D:=Dy*2-Dx; Ai:=2*(Dy-Dx);
  712.       Bi:=Dy*2; X:=xa; Y:=ya;
  713.       IF (X>=0) AND (Y>=0) AND (X<=Xmax) AND (Y<=Ymax) THEN SetPix(X,Y,color);
  714.       FOR X:=xa+1 TO xb DO
  715.        BEGIN
  716.          IF (D>=0) THEN
  717.           ASM
  718.             MOV AX,Y
  719.             ADD AX,Yi
  720.             MOV Y,AX
  721.             MOV AX,D
  722.             ADD AX,Ai
  723.             MOV D,AX
  724.           END ELSE ASM
  725.             MOV AX,D
  726.             ADD AX,Bi
  727.             MOV D,AX
  728.           END;
  729.          IF (X>=0) AND (Y>=0) AND (X<=Xmax) AND (Y<=Ymax) THEN SetPix(X,Y,color);
  730.        END;
  731.     END;
  732.  END;
  733.  
  734. PROCEDURE PutMap(x,y:WORD; VAR map:POINTER; ignore:BYTE); ASSEMBLER;
  735.  ASM
  736.  END;
  737.  
  738. PROCEDURE GetMap(x,y:WORD; VAR map:POINTER); ASSEMBLER;
  739.  ASM
  740.  END;
  741.  
  742. {╔═════════════════════════════════════════════════════════════════════════╗
  743.  ║ DAC color controller procedures                                         ║
  744.  ╚═════════════════════════════════════════════════════════════════════════╝}
  745.  
  746. PROCEDURE DacSetSingle(nr,red,green,blue:BYTE); ASSEMBLER;
  747.  ASM
  748.      MOV  dx,$3C8
  749.      MOV  al,nr
  750.      OUT  dx,al
  751.      MOV  dx,$3C9
  752.      MOV  al,red
  753.      OUT  dx,al
  754.      MOV  al,green
  755.      OUT  dx,al
  756.      MOV  al,blue
  757.      OUT  dx,al
  758.  END;
  759.  
  760. PROCEDURE DacGetSingle(nr:BYTE; VAR red,green,blue:BYTE); ASSEMBLER;
  761.  ASM
  762.      MOV  dx,$3C7
  763.      MOV  al,nr
  764.      OUT  dx,al
  765.      MOV  dx,$3C9
  766.      LES  di,red
  767.      IN   al,dx
  768.      MOV  es:[di],al
  769.      LES  di,green
  770.      IN   al,dx
  771.      MOV  es:[di],al
  772.      LES  di,blue
  773.      IN   al,dx
  774.      MOV  es:[di],al
  775.  END;
  776.  
  777. PROCEDURE DacSetPalette(dac:DACBUFFER); ASSEMBLER;
  778.  ASM
  779.      PUSH ds
  780.      LDS  si,dac
  781.      MOV  dx,$3C8
  782.      MOV  al,0
  783.      MOV  cx,768
  784.      OUT  dx,al
  785.      INC  dx
  786.      REP  OUTSB
  787.      POP  ds
  788.  END;
  789.  
  790. PROCEDURE DacGetPalette(VAR dac:DACBUFFER); ASSEMBLER;
  791.  ASM
  792.      LES  dx,dac
  793.      MOV  ax,$1017
  794.      MOV  bx,$0000
  795.      MOV  cx,$0100
  796.      INT  $10
  797.  END;
  798.  
  799. PROCEDURE DacSavePalette(name:STRING; dac:DACBUFFER);
  800.  VAR fil:FILE OF BYTE; t,u:BYTE;
  801.  BEGIN
  802.    Assign(fil,name); ReWrite(fil);
  803.    FOR u:=0 TO 2 DO FOR t:=0 TO 255 DO Write(fil,dac[t,u]);
  804.    Close(fil);
  805.  END;
  806.  
  807. PROCEDURE DacLoadPalette(name:STRING; VAR dac:DACBUFFER);
  808.  VAR fil:FILE OF BYTE; t,u:BYTE;
  809.  BEGIN
  810.    Assign(fil,name); Reset(fil);
  811.    FOR u:=0 TO 2 DO FOR t:=0 TO 255 DO Read(fil,dac[t,u]);
  812.    Close(fil);
  813.  END;
  814.  
  815. {╔═════════════════════════════════════════════════════════════════════════╗
  816.  ║ Procedures for handling fonts, mostly based on pointers                 ║
  817.  ╚═════════════════════════════════════════════════════════════════════════╝}
  818.  
  819. {$L Romans.Obj} PROCEDURE RomansFont; EXTERNAL;
  820.  
  821. FUNCTION  MainFont(font:POINTER):POINTER;
  822.  BEGIN
  823.    MainFont:=Ptr(FontSegment,FontOffset-1);
  824.    FontSegment:=Seg(font^); FontOffset:=Ofs(font^)+1;
  825.    FontHeight:=Mem[FontSegment:FontOffset-1];
  826.  END;
  827.  
  828. FUNCTION  WhatFont:POINTER;
  829.  BEGIN
  830.    WhatFont:=Ptr(FontSegment,FontOffset-1);
  831.  END;
  832.  
  833. PROCEDURE PlotChar(x,y:WORD; ch,color,bg:BYTE);
  834.  VAR a,b:BYTE;
  835.  BEGIN
  836.    IF (x<0) OR (y<0) OR (x>xMax-8) OR (y>yMax-FontHeight) THEN Exit;
  837.    FOR a:=0 TO 7 DO FOR b:=0 TO FontHeight-1 DO
  838.    IF Mem[FontSegment:FontOffset+ch*FontHeight+b] AND
  839.       (128 SHR (a AND 7))=(128 SHR (a AND 7))
  840.    THEN SetPix(x+a,y+b,color) ELSE SetPix(x+a,y+b,bg);
  841.  END;
  842.  
  843. PROCEDURE DrawChar(x,y:WORD; ch,color:BYTE);
  844.  VAR a,b:BYTE;
  845.  BEGIN
  846.    IF (x<0) OR (y<0) OR (x>xMax-8) OR (y>yMax-FontHeight) THEN Exit;
  847.    FOR a:=0 TO 7 DO FOR b:=0 TO FontHeight-1 DO
  848.    IF Mem[FontSegment:FontOffset+ch*FontHeight+b] AND
  849.       (128 SHR (a AND 7))=(128 SHR (a AND 7))
  850.    THEN SetPix(x+a,y+b,color);
  851.  END;
  852.  
  853. PROCEDURE WriteLine(x,y:WORD; s:STRING; color,bg:BYTE);
  854.  VAR a:BYTE;
  855.  BEGIN
  856.    FOR a:=1 TO Len(s) DO IF color=bg
  857.    THEN DrawChar(x+(a-1)*8,y,Ord(S[a]),color   )
  858.    ELSE PlotChar(x+(a-1)*8,y,Ord(S[a]),color,bg);
  859.  END;
  860.  
  861. {╔═════════════════════════════════════════════════════════════════════════╗
  862.  ║ Mouse routines with interrupt handling on $1C                           ║
  863.  ╚═════════════════════════════════════════════════════════════════════════╝}
  864.  
  865. VAR       MouseOldInterrupt:POINTER;
  866.           MouseX,MouseY:WORD;
  867.  
  868. {$F+}
  869. PROCEDURE MouseInterrupt; INTERRUPT;
  870.  BEGIN
  871.     ASM
  872.      MOV  ax,$0003
  873.      INT  $33
  874.      MOV  MouseButtons,bl
  875.      MOV  MouseXpos,cx
  876.      MOV  MouseYpos,dx
  877.     END;
  878.    InLine($9C);
  879.    IF NOT MouseHardWare AND ((MouseX<>MouseXpos) OR (MouseY<>MouseYpos)) AND
  880.       (MouseState=ON) THEN WITH MouseBob DO
  881.     BEGIN
  882.       SetBack(MouseX,MouseY);
  883.       MouseX:=MouseXpos;
  884.       MouseY:=MouseYPos;
  885.       GetBack(MouseX,MouseY);
  886.       SetFore(MouseX,MouseY);
  887.     END;
  888.  END;
  889.  
  890. {$F-}
  891.  
  892. PROCEDURE MouseSetArrowBob;
  893.  BEGIN
  894.    WITH MouseBob DO
  895.     BEGIN
  896.       Ignore:=1; px:=7; py:=7;
  897.       {********} Fore[0,0]:=00; Fore[1,0]:=00; Fore[2,0]:=00; Fore[3,0]:=00;
  898.                  Fore[4,0]:=00; Fore[5,0]:=00; Fore[6,0]:=00; Fore[7,0]:=00;
  899.       {*-----* } Fore[0,1]:=00; Fore[1,1]:=15; Fore[2,1]:=15; Fore[3,1]:=15;
  900.                  Fore[4,1]:=15; Fore[5,1]:=15; Fore[6,1]:=00; Fore[7,1]:=01;
  901.       {*----*  } Fore[0,2]:=00; Fore[1,2]:=15; Fore[2,2]:=15; Fore[3,2]:=15;
  902.                  Fore[4,2]:=15; Fore[5,2]:=00; Fore[6,2]:=01; Fore[7,2]:=01;
  903.       {*-----* } Fore[0,3]:=00; Fore[1,3]:=15; Fore[2,3]:=15; Fore[3,3]:=15;
  904.                  Fore[4,3]:=15; Fore[5,3]:=15; Fore[6,3]:=00; Fore[7,3]:=01;
  905.       {*------*} Fore[0,4]:=00; Fore[1,4]:=15; Fore[2,4]:=15; Fore[3,4]:=15;
  906.                  Fore[4,4]:=15; Fore[5,4]:=15; Fore[6,4]:=15; Fore[7,4]:=00;
  907.       {*-*---* } Fore[0,5]:=00; Fore[1,5]:=15; Fore[2,5]:=00; Fore[3,5]:=15;
  908.                  Fore[4,5]:=15; Fore[5,5]:=15; Fore[6,5]:=00; Fore[7,5]:=01;
  909.       {** *-*  } Fore[0,6]:=00; Fore[1,6]:=00; Fore[2,6]:=01; Fore[3,6]:=00;
  910.                  Fore[4,6]:=15; Fore[5,6]:=00; Fore[6,6]:=01; Fore[7,6]:=01;
  911.       {*   *   } Fore[0,7]:=00; Fore[1,7]:=01; Fore[2,7]:=01; Fore[3,7]:=01;
  912.                  Fore[4,7]:=00; Fore[5,7]:=01; Fore[6,7]:=01; Fore[7,7]:=01;
  913.     END;
  914.     ASM
  915.      MOV  AX,SEG MouseHardBob
  916.      MOV  ES,AX
  917.      MOV  DI,OFFSET MouseHardBob
  918.      MOV  AX,0000000000000000b; STOSW
  919.      MOV  AX,0000000000000000b; STOSW
  920.      MOV  AX,0011111111111111b; STOSW { oo           }
  921.      MOV  AX,0001111111111111b; STOSW { o o          }
  922.      MOV  AX,0000111111111111b; STOSW { o  o         }
  923.      MOV  AX,0000011111111111b; STOSW { o   o        }
  924.      MOV  AX,0000001111111111b; STOSW { o    o       }
  925.      MOV  AX,0000000111111111b; STOSW { o     o      }
  926.      MOV  AX,0000000011111111b; STOSW { o      o     }
  927.      MOV  AX,0000000001111111b; STOSW { o       o    }
  928.      MOV  AX,0000000000111111b; STOSW { o        o   }
  929.      MOV  AX,0000000000011111b; STOSW { o     ooooo  }
  930.      MOV  AX,0000000111111111b; STOSW { o  o  o      }
  931.      MOV  AX,0001000011111111b; STOSW { o o o  o     }
  932.      MOV  AX,0011000011111111b; STOSW { oo  o  o     }
  933.      MOV  AX,1111100001111111b; STOSW {      o  o    }
  934.      MOV  AX,1111100001111111b; STOSW {      o  o    }
  935.      MOV  AX,1111110001111111b; STOSW {       ooo    }
  936.      MOV  AX,0000000000000000b; STOSW
  937.      MOV  AX,0100000000000000b; STOSW
  938.      MOV  AX,0110000000000000b; STOSW
  939.      MOV  AX,0111000000000000b; STOSW
  940.      MOV  AX,0111100000000000b; STOSW
  941.      MOV  AX,0111110000000000b; STOSW
  942.      MOV  AX,0111111000000000b; STOSW
  943.      MOV  AX,0111111100000000b; STOSW
  944.      MOV  AX,0111111110000000b; STOSW
  945.      MOV  AX,0111110000000000b; STOSW
  946.      MOV  AX,0110110000000000b; STOSW
  947.      MOV  AX,0100011000000000b; STOSW
  948.      MOV  AX,0000011000000000b; STOSW
  949.      MOV  AX,0000001100000000b; STOSW
  950.      MOV  AX,0000001100000000b; STOSW
  951.      MOV  AX,0000000000000000b; STOSW
  952.      MOV  ax,SEG MouseHardBob
  953.      MOV  es,ax
  954.      MOV  si,OFFSET MouseHardBob
  955.      MOV  bx,es:[si]
  956.      MOV  cx,es:[si+2]
  957.      ADD  si,4
  958.      MOV  dx,si
  959.      MOV  ax,$0009
  960.      INT  $33
  961.     END;
  962.  END;
  963.  
  964. PROCEDURE MouseSetClockBob;
  965.  BEGIN
  966.     ASM
  967.      MOV  AX,SEG MouseHardBob
  968.      MOV  ES,AX
  969.      MOV  DI,OFFSET MouseHardBob
  970.      MOV  AX,0000000000000000b; STOSW
  971.      MOV  AX,0000000000000000b; STOSW
  972.      MOV  AX,1111100000111111b; STOSW
  973.      MOV  AX,1110000000001111b; STOSW
  974.      MOV  AX,1100000000000111b; STOSW
  975.      MOV  AX,1000000000000011b; STOSW
  976.      MOV  AX,1000000000000011b; STOSW
  977.      MOV  AX,0000000000000001b; STOSW
  978.      MOV  AX,0000000000000001b; STOSW
  979.      MOV  AX,0000000000000001b; STOSW
  980.      MOV  AX,0000000000000001b; STOSW
  981.      MOV  AX,0000000000000001b; STOSW
  982.      MOV  AX,1000000000000011b; STOSW
  983.      MOV  AX,1000000000000011b; STOSW
  984.      MOV  AX,1100000000000111b; STOSW
  985.      MOV  AX,1110000000001111b; STOSW
  986.      MOV  AX,1111100000111111b; STOSW
  987.      MOV  AX,1111111111111111b; STOSW
  988.      MOV  AX,0000000000000000b; STOSW
  989.      MOV  AX,0000011011000000b; STOSW
  990.      MOV  AX,0001011111010000b; STOSW
  991.      MOV  AX,0011111011111000b; STOSW
  992.      MOV  AX,0011111011111000b; STOSW
  993.      MOV  AX,0101111011110100b; STOSW
  994.      MOV  AX,0111111011111100b; STOSW
  995.      MOV  AX,0011110000011000b; STOSW
  996.      MOV  AX,0111111011111100b; STOSW
  997.      MOV  AX,0101111111110100b; STOSW
  998.      MOV  AX,0011111111111000b; STOSW
  999.      MOV  AX,0011111111111000b; STOSW
  1000.      MOV  AX,0001011111010000b; STOSW
  1001.      MOV  AX,0000011011000000b; STOSW
  1002.      MOV  AX,0000000000000000b; STOSW
  1003.      MOV  AX,0000000000000000b; STOSW
  1004.      MOV  ax,SEG MouseHardBob
  1005.      MOV  es,ax
  1006.      MOV  si,OFFSET MouseHardBob
  1007.      MOV  bx,es:[si]
  1008.      MOV  cx,es:[si+2]
  1009.      ADD  si,4
  1010.      MOV  dx,si
  1011.      MOV  ax,$0009
  1012.      INT  $33
  1013.     END;
  1014.  END;
  1015.  
  1016. PROCEDURE MouseUseHardware;
  1017.  VAR ms:BOOLEAN;
  1018.  BEGIN
  1019.    ms:=MouseState; Mouse(OFF); MouseHardware:=ON; Mouse(ms);
  1020.  END;
  1021.  
  1022. PROCEDURE MouseUseSoftware;
  1023.  VAR ms:BOOLEAN;
  1024.  BEGIN
  1025.    ms:=MouseState; Mouse(OFF); MouseHardware:=OFF; Mouse(ms);
  1026.  END;
  1027.  
  1028. FUNCTION  MouseReset:BOOLEAN; ASSEMBLER;
  1029.  ASM
  1030.      MOV  ax,$0000
  1031.      INT  $33
  1032.  END;
  1033.  
  1034. PROCEDURE Mouse(mode:BOOLEAN);
  1035.  BEGIN
  1036.    IF MouseState=mode THEN Exit; MouseState:=mode;
  1037.    IF MouseHardware THEN
  1038.     ASM
  1039.      MOV  ax,$0001
  1040.      CMP  mode,ON
  1041.      JE   @nx
  1042.      MOV  ax,$0002
  1043. @nx: INT  $33
  1044.     END
  1045.    ELSE
  1046.     BEGIN
  1047.       IF mode=ON THEN WITH MouseBob DO
  1048.        BEGIN
  1049.          MouseX:=MouseXpos;
  1050.          MouseY:=MouseYpos;
  1051.          GetBack(MouseX,MouseY);
  1052.          SetFore(MouseX,MouseY);
  1053.        END
  1054.       ELSE MouseBob.SetBack(MouseX,MouseY);
  1055.     END;
  1056.  END;
  1057.  
  1058. PROCEDURE MouseSetPosition(x,y:WORD); ASSEMBLER;
  1059.  ASM
  1060.      MOV  cx,x
  1061.      MOV  dx,y
  1062.      MOV  ax,$0004
  1063.      INT  $33
  1064.  END;
  1065.  
  1066. PROCEDURE MouseSetRange(xa,ya,xb,yb:WORD);
  1067.  BEGIN
  1068.  END;
  1069.  
  1070. FUNCTION  MouseInitiateInterrupt:BOOLEAN;
  1071.  BEGIN
  1072.    IF NOT MouseReset THEN BEGIN MouseInitiateInterrupt:=FALSE; Exit; END;
  1073.    IF MouseState=ON  THEN Mouse(OFF);
  1074.  
  1075.    MouseOldInterrupt:=InterruptVector(@MouseInterrupt,$1C);
  1076.    IF MouseHardWare THEN MouseUseHardWare
  1077.                     ELSE MouseUseSoftWare;
  1078.    MouseState:=OFF;
  1079.    MouseInitiateInterrupt:=TRUE;
  1080.  END;
  1081.  
  1082. PROCEDURE MouseEndInterrupt;
  1083.  BEGIN
  1084.    InterruptVector(MouseOldInterrupt,$1C);
  1085.  END;
  1086.  
  1087. BEGIN
  1088.   WhatGfxMode:=UnknownGfxMode;
  1089.   MainFont(@RomansFont);
  1090.   MouseState:=OFF;
  1091.   MouseHardWare:=ON;
  1092. END.